﻿using System;
using System.Collections.Generic;

namespace K3Cloud.WebApi.Core.IoC.DataEntity
{
    /// <summary>
    /// K3编码
    /// </summary>
    public interface IK3Number
    {
        string ToString();
    }

    /// <summary>
    /// 编码
    /// </summary>
    public sealed class K3Number : IK3Number
    {
        public string FNumber { get; set; }

        /// <summary>
        /// 编码
        /// </summary>
        private K3Number(string fNumber)
        {
            FNumber = fNumber;
        }

        public override string ToString()
        {
            return $"{{\"FNumber\": \"{FNumber}\"}}";
        }

        /// <summary>
        /// 编码
        /// </summary>
        public static K3Number Parse(string fnumber)
        {
            if (string.IsNullOrEmpty(fnumber))
            {
                throw new ArgumentNullException(nameof(fnumber));
            }
            return new(fnumber);
        }

        public static bool operator ==(K3Number left, K3Number right)
        {
            return ReferenceEquals(left, right) || (left is not null && right is not null && left.FNumber == right.FNumber);
        }
        public static bool operator ==(K3Number left, string right)
        {
            return ReferenceEquals(left, right) || (left is not null && right is not null && left.FNumber == right);
        }
        /// <summary>
        /// 判断两个K3Number实例是否不相等
        /// </summary>
        /// <param name="left">第一个K3Number实例</param>
        /// <param name="right">第二个K3Number实例</param>
        /// <returns>如果不相等则为true，否则为false</returns>
        public static bool operator !=(K3Number left, K3Number right)
        {
            return !(left == right);
        }
        public static bool operator !=(K3Number left, string right)
        {
            return !(left.FNumber == right);
        }

        /// <summary>
        /// 确定指定的对象是否等于当前对象
        /// </summary>
        /// <param name="obj">要与当前对象进行比较的对象</param>
        /// <returns>如果指定的对象等于当前对象，则为 true；否则为 false</returns>
        public override bool Equals(object? obj)
        {
            return obj is K3Number other && FNumber == other.FNumber;
        }

        public override int GetHashCode()
        {
            return FNumber.GetHashCode();
        }

        public static implicit operator string(K3Number number) { return number.ToString(); }
        public static implicit operator K3Number(string number) { return Parse(number); }
    }

    /// <summary>
    /// 自定义编码
    /// <![CDATA[用的比较少,比如：业务源单类型]]>
    /// </summary>
    public sealed class K3KeyValue : IK3Number
    {
        public string FKey { get; set; }
        public object FValue { get; set; }
        /// <summary>
        /// 自定义编码
        /// </summary>
        private K3KeyValue(string key, object value)
        {
            FKey = key;
            FValue = value;
        }

        public override string ToString()
        {
            return FValue.GetType().IsValueType ? $"{{\"{FKey}\": {FValue}}}" : $"{{\"{FKey}\": \"{FValue}\"}}";
        }

        /// <summary>
        /// 自定义编码(用的比较少)
        /// </summary>
        public static K3KeyValue Parse(string key, object value)
        {
            if (string.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException(nameof(key));
            }
            return new(key, value);
        }

        public override bool Equals(object? obj)
        {
            return obj is K3KeyValue value &&
                   FKey == value.FKey &&
                   EqualityComparer<object>.Default.Equals(FValue, value.FValue);
        }

        public override int GetHashCode()
        {
#if NETSTANDARD2_1_OR_GREATER
            return HashCode.Combine(FKey, FValue);
#else
            return FKey.GetHashCode() ^ FValue.GetHashCode();
#endif
        }

        public static bool operator ==(K3KeyValue left, K3KeyValue right)
        {
            return ReferenceEquals(left, right)
|| (left is not null && right is not null && left.FKey == right.FKey && left.FValue.GetHashCode() == right.FValue.GetHashCode());
        }
        public static bool operator !=(K3KeyValue left, K3KeyValue right)
        {
            return !(left == right);
        }
        public static implicit operator string(K3KeyValue kv) { return kv.ToString(); }
        /// <summary>
        /// 自定义kv
        /// </summary>
        /// <param name="kvStr">
        /// 用:分割,左边是key,右边是value 例如:{"FName":"测试"}  FName:测试
        /// 数字类型的value需要加上D,例如:{"FPrice":100.00}  FPrice|D:100.00
        /// </param>
        public static implicit operator K3KeyValue(string kvStr)
        {
            try
            {
                string[] obj = kvStr.Split(':');
                if (obj.Length != 2) { throw new ArgumentException(); }
                string key = obj[0].Replace("{", "").Replace("\"", "").Trim();
                object value = obj[1].Replace("}", "").Replace("\"", "").Trim();
                string[] kt = key.Split('|');
                if (kt.Length == 2)
                {
                    if (kt[0].Trim().Equals("D", StringComparison.OrdinalIgnoreCase))
                    {
                        key = kt[1].Trim();
                        value = decimal.Parse(value.ToString()!);
                    }
                    else if (kt[1].Trim().Equals("D", StringComparison.OrdinalIgnoreCase))
                    {
                        key = kt[0].Trim();
                        value = decimal.Parse(value.ToString()!);
                    }
                }
                return Parse(key, value);
            }
            catch (Exception)
            {
                throw;
            }
        }
    }

    /// <summary>
    /// 用户
    /// </summary>
    public sealed class K3User : IK3Number
    {
        public int FUserID { get; set; }

        private K3User(int FUserID)
        {
            this.FUserID = FUserID;
        }
        public override string ToString()
        {
            return $"{{\"FUSERID\": {FUserID}}}";
        }
        /// <summary>
        /// 用户内码
        /// </summary>
        public static K3User Parse(int FUserID)
        {
            return new(FUserID);
        }
        /// <summary>
        /// 
        /// </summary>
        public static bool operator ==(K3User left, K3User right)
        {
            return ReferenceEquals(left, right) || (left is not null && right is not null && left.FUserID == right.FUserID);
        }
        /// <summary>
        /// 
        /// </summary>
        public static bool operator ==(K3User left, int right)
        {
            return left is not null && left.FUserID == right;
        }
        /// <summary>
        /// 
        /// </summary>
        public static bool operator !=(K3User left, K3User right)
        {
            return !(left == right);
        }
        /// <summary>
        /// 
        /// </summary>
        public static bool operator !=(K3User left, int right)
        {
            return !(left.FUserID == right);
        }
        /// <summary>
        /// 
        /// </summary>
        public override bool Equals(object? obj)
        {
            return obj is K3User other && FUserID == other.FUserID;
        }
        /// <summary>
        /// 
        /// </summary>
        public override int GetHashCode()
        {
            return FUserID.GetHashCode();
        }

        public static implicit operator int(K3User UserID) { return UserID; }
        public static implicit operator K3User(int UserID) { return Parse(UserID); }
    }
}
